package com.slingshot.identitysdk.util

import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import android.support.v4.content.FileProvider
import android.support.v7.app.AppCompatActivity
import android.util.Log
import com.liushiyu.tooltip.Tooltip
import com.liushiyu.tooltip.core.sheet.SheetDialog
import com.slingshot.identitylibrary.Slingshot
import com.slingshot.identitylibrary.idinfo.callback.IDInfoCallback
import com.slingshot.identitysdk.common.SlingshotData
import com.slingshot.identitysdk.viewmodel.SlingshotViewModel
import org.json.JSONObject
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream


/**
 * @author liu shuai
 * 描述：照片工具类
 */
class PhotoUtil {

    companion object {
        const val AUTHORITY = "com.slingshot.identitysdk.fileprovider"
        const val REQUEST_CODE_CAPTURE_RAW = 2
        const val REQUEST_CODE_CAPTURE = 3
        const val REQUEST_CODE_CAPTURE_CROP = 4
        const val REQUEST_CODE_ALBUM = 5

        var imgUri: Uri? = null
        var imageFile: File? = null
        var imageCropFile: File? = null
    }

    private var userPhotoPath = ""

    private lateinit var activity: AppCompatActivity
    private lateinit var slingshotViewModel: SlingshotViewModel

    private var sheetList: ArrayList<String> = ArrayList()

    private var loadingDialog = Tooltip.loading().message("正在扫描..").build()

    private var extractType = -1

    init {
        init()
    }

    private fun init() {
        sheetList.clear()
        sheetList.add("拍照")
        sheetList.add("相册")
    }

    fun init(activity: AppCompatActivity, slingshotViewModel: SlingshotViewModel) {
        this.activity = activity
        this.slingshotViewModel = slingshotViewModel
    }

    /**
     * 读取身份证正面（人脸）
     * */
    fun scanIdentityFace() {
        extractType = 1
        showSheetDialog()
    }

    /**
     * 读取身份证背面（国徽）
     * */
    fun scanIdentityNationalEmblem() {
        extractType = 2
        showSheetDialog()
    }

    /**
     * 读取人物信息
     * */
    fun extractFaceDetect() {
        extractType = 3
        showSheetDialog()
    }

    private fun showSheetDialog() {
        Tooltip.sheet()
            .setOptions(sheetList)
            .setSpecialButtonText("取消")
            .setCancelable(true)
            .setCancelableBackButtonCanGoAway(true)
            .setSheetListener(object : SheetDialog.SheetDialogListener {
                override fun onOptionSelected(option: JSONObject) {
                    val index = option.getString("index")
                    when (index.toInt()) {
                        0 -> {
                            takePhoto()
                        }
                        1 -> {
                            album()
                        }
                    }
                }

                override fun onDismiss() {

                }
            }).build().show(activity.supportFragmentManager, "navigationTimeLayoutClick")
    }


    private fun takePhoto() {
        gotoCaptureRaw()
    }

    private fun album() {
        gotoGallery()
    }

    //拍照(返回原始图)
    private fun gotoCaptureRaw() {
        imageFile = FileUtil.createImageFile()
        imageFile?.let {
            val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
                imgUri = FileProvider.getUriForFile(
                    activity,
                    AUTHORITY, it
                )
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri)
            } else {
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(it))
            }

            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString())
            intent.resolveActivity(activity.packageManager)?.let {
                activity.startActivityForResult(intent, REQUEST_CODE_CAPTURE_RAW)
            }
        }
    }

    //打开系统相册
    private fun gotoGallery() {
        val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
        activity.startActivityForResult(intent, REQUEST_CODE_ALBUM)
    }

    fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode == Activity.RESULT_OK) {
            when (requestCode) {
                REQUEST_CODE_CAPTURE -> { //拍照成功后，裁剪
                    val sourceUri = FileProvider.getUriForFile(
                        activity,
                        AUTHORITY,
                        imageFile!!
                    ) //通过FileProvider创建一个content类型的Uri
                    gotoCrop(sourceUri)
                }
                REQUEST_CODE_ALBUM -> { //从相册选择照片后，裁剪
                    data?.let { it ->
                        it.data?.let { dataUri ->
                            gotoCrop(dataUri)
                        }
                    }
                }
                REQUEST_CODE_CAPTURE_RAW -> { //拍照成功后，压缩图片，显示结果
                    imageFile?.let {
                        userPhotoPath = it.absolutePath
                        when(extractType) {
                            1 -> {
                                extractIdCardBack(userPhotoPath)
                            }
                            2 -> {
                                extractIdCardFront(userPhotoPath)
                            }
                            3 -> {
                                extractFaceDetect(userPhotoPath)
                            }
                        }
                    }
                }
                REQUEST_CODE_CAPTURE_CROP -> {   //裁剪成功后，显示结果
                    imageCropFile?.let {
                        userPhotoPath = it.absolutePath
                        when(extractType) {
                            1 -> {
                                extractIdCardBack(userPhotoPath)
                            }
                            2 -> {
                                extractIdCardFront(userPhotoPath)
                            }
                            3 -> {
                                extractFaceDetect(userPhotoPath)
                            }
                        }
                    }
                }
            }
        }
    }

    //裁剪
    private fun gotoCrop(sourceUri: Uri) {
        imageCropFile = FileUtil.createImageFile(true)
        imageCropFile?.let {

            val intent = Intent("com.android.camera.action.CROP")
            intent.putExtra("crop", "true")
            intent.putExtra("aspectX", 1)    //X方向上的比例
            intent.putExtra("aspectY", 1)    //Y方向上的比例
            intent.putExtra("outputX", 480)  //裁剪区的宽
            intent.putExtra("outputY", 480) //裁剪区的高
            intent.putExtra("scale ", false)  //是否保留比例
            intent.putExtra("return-data", false)
            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString())

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) //添加这一句表示对目标应用临时授权该Uri所代表的文件
                intent.setDataAndType(sourceUri, "image/*")  //设置数据源
                val imgCropUri = Uri.fromFile(it)
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imgCropUri) //设置输出  不需要ContentUri,否则失败
            } else {
                intent.setDataAndType(Uri.fromFile(imageFile!!), "image/*")
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(it))
            }
            activity.startActivityForResult(intent, REQUEST_CODE_CAPTURE_CROP)
        }
    }

    private fun extractIdCardFront(path: String) {
        log("正在读取身份证正面信息 path = $path")

        val photoFile = File(path)
        log("压缩前的图片大小：photoFile.length() = ${FileSizeUtil.getAutoFileOrFilesSize(path)}")
        samplingRateCompress(path, photoFile)
        log("压缩后的图片大小：photoFile.length() = ${FileSizeUtil.getAutoFileOrFilesSize(path)}")
        loadingDialog = Tooltip.loading().message("正在读取身份证正面信息..").build()
        loadingDialog.show(activity.supportFragmentManager, "extractIdCardFront")
        Slingshot.extractIdCardNationalEmblem(File(path), object : IDInfoCallback {
            override fun extractStart() {
                super.extractStart()
                log("extractStart")
            }

            override fun extractSuccess(result: String) {
                loadingDialog.dismiss()
                log("正在读取身份证正面信息 成功 result = $result")
                val data = SlingshotData(1, result, null)
                slingshotViewModel.setSlingshotData(data)
            }

            override fun extractFail(e: Throwable) {
                loadingDialog.dismiss()
                log("正在读取身份证正面信息 失败 e = ${e.message}")
                val data = SlingshotData(2, e.message, null)
                slingshotViewModel.setSlingshotData(data)
            }
        })
    }

    private fun extractIdCardBack(path: String) {
        log("正在读取身份证背面信息 path = $path")

        val photoFile = File(path)
        log("压缩前的图片大小：photoFile.length() = ${FileSizeUtil.getAutoFileOrFilesSize(path)}")
        samplingRateCompress(path, photoFile)
        log("压缩后的图片大小：photoFile.length() = ${FileSizeUtil.getAutoFileOrFilesSize(path)}")
        loadingDialog = Tooltip.loading().message("正在读取身份证背面信息..").build()
        loadingDialog.show(activity.supportFragmentManager, "extractIdCardBack")
        Slingshot.extractIdCardFace(File(path), object : IDInfoCallback {
            override fun extractStart() {
                super.extractStart()
                log("extractStart")
            }

            override fun extractSuccess(result: String) {
                loadingDialog.dismiss()
                log("正在读取身份证背面信息 成功 result = $result")
                val data = SlingshotData(1, result, null)
                slingshotViewModel.setSlingshotData(data)
            }

            override fun extractFail(e: Throwable) {
                loadingDialog.dismiss()
                log("${e.message}")
                val data = SlingshotData(2, e.message, null)
                slingshotViewModel.setSlingshotData(data)
            }
        })
    }

    private fun extractFaceDetect(path: String) {
        val photoFile = File(path)
        log("压缩前的图片大小：photoFile.length() = ${FileSizeUtil.getAutoFileOrFilesSize(path)}")
        samplingRateCompress(path, photoFile)
        log("压缩后的图片大小：photoFile.length() = ${FileSizeUtil.getAutoFileOrFilesSize(path)}")
        Slingshot.extractFaceDetect(File(path), object : IDInfoCallback {
            override fun extractStart() {
                super.extractStart()
                loadingDialog = Tooltip.loading().message("正在扫描人物信息..").build()
                loadingDialog.show(activity.supportFragmentManager, "extractFaceDetect")
            }

            override fun extractSuccess(result: String) {
                loadingDialog.dismiss()
                val data = SlingshotData(1, result, null)
                slingshotViewModel.setSlingshotData(data)
            }

            override fun extractFail(e: Throwable) {
                loadingDialog.dismiss()
                val data = SlingshotData(2, e.message, null)
                slingshotViewModel.setSlingshotData(data)
            }
        })
    }

    /**
     * 5.采样率压缩（设置图片的采样率，降低图片像素）
     *
     * @param filePath
     * @param file
     */
    private fun samplingRateCompress(filePath: String, file: File) {
        // 数值越高，图片像素越低

        val bitmap = BitmapFactory.decodeFile(filePath, BitmapFactory.Options())
        val baos = ByteArrayOutputStream()
        // 把压缩后的数据存放到baos中
        bitmap.compress(Bitmap.CompressFormat.JPEG, 60, baos)
        try {
            if (file.exists()) {
                file.delete()
            } else {
                file.createNewFile()
            }
            val fos = FileOutputStream(file)
            fos.write(baos.toByteArray())
            fos.flush()
            fos.close()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun log(string: String) {
        Log.e("PhotoUtil", string)
    }
}